package com.ZeroCarbon.filters;

import com.ZeroCarbon.entity.PathProperties;
import com.ZeroCarbon.utils.JwtTool;
import lombok.RequiredArgsConstructor;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.OrderedGatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.server.ServerWebExchange;

@Component
@RequiredArgsConstructor
public class AuthGatewayFilterFactory extends AbstractGatewayFilterFactory<Object> {

    /**
     * 路径参数
     */
    private final PathProperties pathProperties;

    /**
     * 路径匹配
     */
    private final AntPathMatcher antPathMatcher = new AntPathMatcher();

    /**
     * Jwt工具
     */
    private final JwtTool jwtTool;

    @Override
    public GatewayFilter apply(Object config) {
        return new OrderedGatewayFilter((exchange, chain) -> {
            ServerHttpRequest request = exchange.getRequest();
            if (isPass(request.getPath().toString())) {
                //放行的不需要token验证
                return chain.filter(exchange);
            }
            //获取请求体的Authorization参数
            String token = request.getHeaders().getFirst("Authorization");
            String userId;
            try {
                userId = jwtTool.parseToken(token);
            } catch (Exception e) {
                e.printStackTrace();
                ServerHttpResponse response = exchange.getResponse();
                //设置响应状态码为401
                response.setStatusCode(HttpStatus.UNAUTHORIZED);
                return response.setComplete();
            }
            String finalUserId = userId;
            //如果token有效，则解析出userId，再交给MVC的拦截器保存到用户信息
            ServerWebExchange serverWebExchange = exchange.mutate()
                    .request(builder -> builder.header("userId", finalUserId))
                    .build();
            return chain.filter(serverWebExchange);
        }, 0);
    }

    //判断是否运行放行
    private boolean isPass(String path) {
        for (String excludePath : pathProperties.getExcludePaths()) {
            if (antPathMatcher.match(excludePath, path)) {
                return true;
            }
        }
        return false;
    }
}
